package com.simba.server.components;

import com.simba.common.log.LogUtil;
import com.simba.server.components.data.KeepAliveInfo;
import org.apache.log4j.Logger;
import org.jboss.netty.channel.Channel;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ChannelsManager
{
	private static class ChannelsManagerHolder
	{
		private static final ChannelsManager INSTANCE = new ChannelsManager();
	}

	protected static final Logger logger = Logger.getLogger(ChannelsManager.class);

	public static ChannelsManager getInstance()
	{
		return ChannelsManagerHolder.INSTANCE;
	}


	private final ConcurrentHashMap<String, KeepAliveInfo> wheelPlcChannels = new ConcurrentHashMap<>();


	public void updateClient(Channel channel){
		if (!this.containsWheelPlcClient(channel))
		{
			this.addWheelPlcClients(channel);
		}
		else
		{
			this.updateWheelPlcTime(channel);
		}
	}

	public void addWheelPlcClients(Channel channel)
	{
		long now = System.currentTimeMillis();
		String key = String.valueOf(channel.getId().shortValue());
		this.wheelPlcChannels.put(key, new KeepAliveInfo(channel, now));
	}


	public void updateWheelPlcTime(Channel channel)
	{
		String key = String.valueOf(channel.getId().shortValue());
		if (this.wheelPlcChannels.containsKey(key)){
			KeepAliveInfo info = this.wheelPlcChannels.get(key);
			if (info != null){
				long now = System.currentTimeMillis();
				info.setKeepAliveTime(now);
			}else {
				this.addWheelPlcClients(channel);
			}
		}else {
			this.addWheelPlcClients(channel);
		}
	}


	public boolean containsWheelPlcClient(Channel channel)
	{
		return this.wheelPlcChannels.containsKey(String.valueOf(channel.getId().shortValue()));
	}

	public void handlerOverTimeLink()
	{
		this.handlerWheelPlcOverTimeLink();
	}


	private void handlerWheelPlcOverTimeLink()
	{
		try
		{
			for (Map.Entry<String, KeepAliveInfo> entry : this.wheelPlcChannels.entrySet()) {
				KeepAliveInfo keepAliveInfo = entry.getValue();
				long recordTime = keepAliveInfo.getKeepAliveTime();
				long currentTime = System.currentTimeMillis();
				long spanTime = currentTime - recordTime;
				if (spanTime > 10 * 1000)
				{
					keepAliveInfo.getChannel().disconnect();
					this.wheelPlcChannels.remove(entry.getKey());
				}
			}
		}
		catch (Exception e)
		{
			LogUtil.LogError(logger, "[ChannelsManager.handlerWheelPlcOverTimeLink] catch exception : " + e.getMessage());
		}
	}
}
